package com.meme.editor.gui;

import javax.swing.JPanel;

import com.meme.editor.EntityObject;

import com.meme.editor.property.Property;
import com.meme.editor.property.PropertyGroupSet;
import com.meme.editor.property.PropertyControl;

import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.BorderLayout;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Font;
import java.awt.FontMetrics;

import java.awt.event.ComponentListener;

import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;

import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;

import org.apache.log4j.Logger;

import com.meme.editor.event.EntityChangedEvent;
import com.meme.editor.event.EntityObjectListener;

import java.util.Hashtable;

public class PropertyEditPanel extends JScrollPane implements EntityObjectListener, ComponentListener, AncestorListener
{
	static Logger logger = Logger.getLogger (PropertyEditPanel.class);
	
	
	class GroupTitleBar extends JLabel
	{
		public GroupTitleBar (String label)
		{
			super (label);
			
			setHorizontalAlignment(SwingConstants.CENTER);
		}
		
		@Override
		public void paintComponent (Graphics g)
		{
			g.setColor (new Color(128, 128, 200));
			g.fillRoundRect(1, 1, getWidth() - 2, getHeight() - 2, 5, 5);
			
			Font f = g.getFont();
			Font f1 = new Font(f.getName(), Font.BOLD, f.getSize());			
			g.setFont (f1);			
			
			super.paintComponent(g);
			//g.setFont (f);
		}
	}
	
	JPanel mInnerPanel;
	EntityObject mDataSource;
	Hashtable <PropertyControl, Property> mContolPropertyLookupTable = new Hashtable <PropertyControl, Property> ();
	
	public PropertyEditPanel ()
	{
		this (null);
	}
	
	public PropertyEditPanel (EntityObject dataSrc)
	{
		super (new JPanel());
		setHorizontalScrollBarPolicy (ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		
		//setVerticalScrollBarPolicy (ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS );
		
		JPanel innerPanel = (JPanel) getViewport().getComponent(0);
		
		addComponentListener (this);
		addAncestorListener (this);
		
		innerPanel.setLayout (new BorderLayout ());
		
		mInnerPanel = new JPanel ();
		
		innerPanel.add (mInnerPanel, BorderLayout.NORTH); 
		innerPanel.add (new JPanel (), BorderLayout.CENTER); 
		
		mInnerPanel.setLayout (new GridBagLayout());
		
		setDataSource (dataSrc);
	}
	
	public void setDataSource (EntityObject dataSrc)
	{
		if ( mDataSource == dataSrc )
			return;
		
		if ( mDataSource != null )
			mDataSource.setPropertyEditPanel (null);
			
		mDataSource = dataSrc;
		
		if ( mDataSource != null )
			mDataSource.setPropertyEditPanel (this);
		

		rebuildComponents ();
		validate ();	
	}
	

	@Override
	public void doLayout ()
	{
		
		//mInnerPanel.updateUI();
		super.doLayout();
	}
	
	protected void rebuildComponents ()
	{
		mInnerPanel.removeAll();
		mContolPropertyLookupTable.clear();

		if ( mDataSource != null )
		{
			int width = getViewport().getWidth ();
			int labelWidth = width * 2 / 5;
			int valueWidth = width - labelWidth;
			
			int row = 0;
			
			
			GridBagConstraints bgc = new GridBagConstraints ();
			GroupTitleBar grouptitle = new GroupTitleBar (mDataSource.getName());
	
			bgc.fill = GridBagConstraints.HORIZONTAL;
			bgc.gridx = 0;
			bgc.gridy = row;
			bgc.gridwidth = 2;
			bgc.ipady = 5;
			mInnerPanel.add(grouptitle, bgc);
			
			++ row;
			
			PropertyGroupSet pm = mDataSource.getPublicProperties();
			for ( int groupID = 0; groupID < pm.getPropertyGroupsCont(); ++ groupID )
			{
	//			GridBagConstraints bgc = new GridBagConstraints ();
	//			GroupTitleBar grouptitle = new GroupTitleBar (pm.getPropertyGroupName (groupID));
	//
	//			bgc.fill = GridBagConstraints.HORIZONTAL;
	//			bgc.gridx = 0;
	//			bgc.gridy = row;
	//			bgc.gridwidth = 2;
	//			bgc.ipady = 5;
	//			mInnerPanel.add(grouptitle, bgc);
	//			
	//			++ row;
				
				for ( int propertyID = 0; propertyID < pm.getPropertiesCountInGroup (groupID); ++ propertyID )
				{
					Property property = pm.getPropertyInGroup (groupID, propertyID);
					
	//				PropertyControl valueControl   = property.getValueControl();
	//				mContolPropertyLookupTable.put (valueControl, property);
	//				valueControl.setPropertyEditPanel (this);
	//				valueControl.update();
					
					JLabel labelComponent = new JLabel (property.getLabel() + ": ");
					labelComponent.setHorizontalAlignment(SwingConstants.RIGHT);
					Dimension labeldim = labelComponent.getPreferredSize();
					labeldim.setSize(labelWidth, labeldim.getHeight());
					labelComponent.setPreferredSize (labeldim);
	
					GridBagConstraints bgc1 = new GridBagConstraints ();
					bgc1.fill = GridBagConstraints.HORIZONTAL;
					bgc1.gridx = 0;
					bgc1.gridy = row;
					bgc1.gridwidth = 1;
					//bgc1.gridheight = valueControl.getGridHeight();
					bgc1.gridheight = property.getControlComponentGridHeight();
					mInnerPanel.add(labelComponent, bgc1);
					
	
					//JComponent valueComponent = valueControl.getComponent();
					JComponent valueComponent = property.getControlComponent();
					Dimension valuedim = valueComponent.getPreferredSize();
					valuedim.setSize(valueWidth, valuedim.getHeight());
					valueComponent.setPreferredSize (valuedim);
	
					GridBagConstraints bgc2 = new GridBagConstraints ();
					bgc2.fill = GridBagConstraints.HORIZONTAL;
					bgc2.gridx = 1;
					bgc2.gridy = row;
					bgc2.gridwidth = 1;
					//bgc2.gridheight = valueControl.getGridHeight();
					bgc2.gridheight = property.getControlComponentGridHeight();
					mInnerPanel.add(valueComponent, bgc2);
					
					++ row;
				}
			}
		}
		
		

		//mInnerPanel.invalidate ();				
		invalidate ();	
	}
	

	
	// PropertyManagerListener
	@Override public void notifyEntityChanged (EntityChangedEvent event)
	{
		logger.assertLog(mDataSource == event.getSource(), "Something wrong.");
		
		if ( ! event.isPublicPropertitesModifiedEvent() )
			return;

		//rebuildComponents ();
		//mInnerPanel.invalidate ();
		//repaint ();
		
		//doLayout ();
		rebuildComponents ();
		validate ();
	}

	// ComponentListener
	@Override public void componentResized(java.awt.event.ComponentEvent event) 
	{
		rebuildComponents ();

		

		//invalidate ();
		
		//doLayout ();
	}
	@Override public void componentMoved(java.awt.event.ComponentEvent arg0) { }
	@Override public void componentShown(java.awt.event.ComponentEvent arg0) { }
	@Override public void componentHidden(java.awt.event.ComponentEvent arg0) { }
	
	@Override public void ancestorAdded(AncestorEvent event) 
	{

	}
	@Override public void ancestorMoved(AncestorEvent event) { }
	@Override public void ancestorRemoved(AncestorEvent event)  
	{
		//setDataSource (null);	
	}
	
}

